#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ldouble;

int T;
int n, m, L, V;
int cans, tans;
struct Cars{
    int di, vi, ai;//Drive in, Speed, AddSpeed
    bool isOS;//Is it over-speed?
    bool ceq;//ed could equal
    int csq;//st could equal
    ldouble st, ed;//When does it OverSpeed

    bool cc;//could be checked
    int cid;//if it could be checked, which checker checked it last time.
}c[100005];
struct CPair{
    int idx;//which car is it
    ldouble st, ed;
    int chkr;//which checker checked it last
    bool operator<(const CPair &T)const{
        return ed < T.ed;
    }
}Line[200005];
int lpos;//Line[]'s pos
int Chkr[100005];
int lstc;
int BNRSearch(ldouble k, bool ceq)
{
    int l = 0, r = m + 1;
    while (l < r - 1)
    {
        int mid = l + (r - l >> 1);
        if (Chkr[mid] < k || (ceq == 1 && Chkr[mid] == k))
            l = mid;
        else
            r = mid;
    }
    return l;
}
int main()
{
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    scanf("%d", &T);
    Chkr[0] = -1;
    while (T--)
    {
        scanf("%d%d%d%d", &n, &m, &L, &V);
        for (int i = 1;i <= n; ++i)
            scanf("%d%d%d", &c[i].di, &c[i].vi, &c[i].ai);
        //Find out when was the car over-speed
        for (int i = 1;i <= n; ++i)
        {
            if (c[i].ai == 0)
            {
                if (c[i].vi > V)
                    c[i].isOS = true, c[i].st = c[i].di, c[i].ed = L, c[i].ceq = true, c[i].csq = true;
                else
                    c[i].isOS = false;
            }
            else if (c[i].ai < 0)
            {
                if (c[i].vi <= V)
                    c[i].isOS = false;
                else
                {
                    ///double dstop = (double)(0 - c[i].vi * c[i].vi) / (2 * c[i].ai);
                    ldouble d = (ldouble)(V * V - c[i].vi * c[i].vi) / (2 * c[i].ai);
                    //if (d < dstop)
                    c[i].isOS = true, c[i].st = c[i].di, c[i].ed = c[i].st + d, c[i].ceq = false, c[i].csq = true;
                    //else
                    //    c[i].isOS = false;
                }
            }
            else
            {
                if (c[i].vi > V)
                    c[i].isOS = true, c[i].st = c[i].di, c[i].ed = L, c[i].ceq = true, c[i].csq = true;
                else
                {
                    ldouble d = (ldouble)(V * V - c[i].vi * c[i].vi) / (2 * c[i].ai);
                    if (c[i].di + d < L)
                        c[i].isOS = true, c[i].st = c[i].di + d, c[i].ed = L, c[i].ceq = true, c[i].csq = false;
                    else
                        c[i].isOS = false;
                }
            }
        }
        for (int i = 1;i <= m; ++i)
            scanf("%d", Chkr + i);
        cans = 0, lpos = 0;
        for (int i = 1;i <= n; ++i)
        {
            if (c[i].isOS == true)
            {
                //printf("%.3lf %.3lf\n", c[i].st, c[i].ed);
                int Chkri = BNRSearch(c[i].ed, c[i].ceq);
                if (Chkr[Chkri] > c[i].st || (c[i].csq == true && Chkr[Chkri] == c[i].st))
                    ++cans, Line[++lpos] = {i, c[i].st, c[i].ed, Chkri};
            }
        }
        sort(Line + 1, Line + lpos + 1);
        lstc = 0, tans = 0;
        for (int i = 1;i <= lpos; ++i)
        {
            if (lstc < Line[i].st)
                ++tans, lstc = Chkr[Line[i].chkr];
        }
        //printf("%d\n", tans);
        printf("%d %d\n", cans, m - tans);
        //printf("####################\n");
    }
    return 0;
}
/*
1
5 5 15 3
0 3 0
12 4 0
1 1 4
5 5 ‐2
6 4 ‐4
2 5 8 9 15
*/
